import { IMetaHandleData, IMetaListData } from '@/views/common/types/operate';
import { useListTable } from '@/hooks/system/useListPage';
import { useMessage } from '@/hooks/web/useMessage';
import { computed, onMounted, ref } from 'vue';
import { useModal, useModalInner } from '@/components/Modal';
import { useDrawer, useDrawerInner } from '@/components/Drawer';
import { assign, isEmpty, isFunction, isNil } from 'lodash-es';
import { ActionItem } from '@/components/Table';
import { usePopupForm } from '@/utils/module/formUtils';
import { usePermission } from '@/hooks/web/usePermission';

interface IApiService {
  useList: (meta: IMetaListData) => {};
  useHandle: (emit, meta: IMetaHandleData) => {};
}
class ApiV1 implements IApiService {
  public useList(meta: IMetaListData) {
    const { hasPermission } = usePermission();
    if (!isNil(meta.auth)) {
      if (!hasPermission(meta.auth)) {
        meta.tableProps.immediate = false;
      }
    }
    const [registerTable, tableMethods, selectMethods, excelMethods] = useListTable(meta.tableProps, meta.excelConfig);

    const { createMessage } = useMessage();

    const showFooter = ref(true);

    const mode = meta.mode ?? 'model';
    let registerLayer: any;
    let openLayer: Fn;
    let userInnerMethod: any;
    if (mode == 'model') {
      const [registerModel, methods] = useModal();
      registerLayer = registerModel;
      userInnerMethod = methods;
      openLayer = methods.openModal;
    } else if (mode == 'drawer') {
      const [registerDrawer, methods] = useDrawer();
      registerLayer = registerDrawer;
      openLayer = methods.openDrawer;
      userInnerMethod = methods;
    }
    onMounted(() => {
      if (!isNil(meta.auth)) {
        if (!hasPermission(meta.auth)) {
          tableMethods.getForm().setProps({ showResetButton: false, showSubmitButton: false });
        }
      }
    });
    const methods = {
      //新增菜单
      handleCreate: () => {
        if (mode == 'model' || mode == 'drawer') {
          openLayer(true, { isUpdate: false });
        } else if (mode == 'page') {
          const addFn = meta.pageMethod?.addFn;
          if (!isNil(addFn) && isFunction(addFn)) {
            addFn();
          }
        }
      },
      //批量删除
      batchDelete: () => {
        const ids = selectMethods.selectedRowKeys.value;
        if (isEmpty(ids)) {
          createMessage.warning('请选择要删除的数据');
          return;
        }
        if (!isNil(meta.delFN) && isFunction(meta.delFN)) {
          meta.delFN(ids).then(() => {
            createMessage.success('删除成功');
            tableMethods.reload();
          });
        }
      },
      //操作菜单
      getTableAction: (record): ActionItem[] => {
        const pkid = meta.pkid ?? 'id';
        const pkidParam = {};
        pkidParam[pkid] = record[pkid];

        let actionItems: ActionItem[] = [];
        if (isFunction(meta.actionItems)) {
          actionItems = meta.actionItems(pkidParam, record);
        }

        const editItem: ActionItem = {
          label: '编辑',
          icon: 'ant-design:edit-outlined',
          // auth: 'system:senior:menu:edit',
          onClick: () => {
            if (mode == 'model' || mode == 'drawer') {
              showFooter.value = true;
              openLayer(true, assign({ isUpdate: true }, pkidParam));
            } else if (mode == 'page') {
              const editFn = meta.pageMethod?.editFn;
              if (!isNil(editFn) && isFunction(editFn)) {
                editFn(pkidParam, record);
              }
            }
          },
        };
        const delItem: ActionItem = {
          label: '删除',
          color: 'error',
          icon: 'ant-design:delete-outlined',
          popConfirm: {
            title: '是否确认删除',
            confirm: async () => {
              if (!isNil(meta.delFN)) {
                let param: string | Recordable<string> = {};
                if (!isNil(meta.queryParams?.delParam)) {
                  if (isFunction(meta.queryParams?.delParam)) {
                    param = await meta.queryParams.delParam(record);
                  } else {
                    meta.queryParams?.delParam.forEach((item) => {
                      if (!isNil(record[item])) {
                        param[item] = record[item];
                      }
                    });
                  }
                } else {
                  param = record[pkid];
                }
                meta.delFN(param).then(() => {
                  createMessage.success('删除成功');
                  tableMethods.reload();
                });
              }
            },
          },
        };

        if (!isNil(meta.editActionItem)) {
          if (isFunction(meta.editActionItem)) {
            actionItems.push(assign(editItem, meta.editActionItem(record)));
          } else {
            actionItems.push(assign(editItem, meta.editActionItem));
          }
        } else {
          actionItems.push(editItem);
        }

        if (!isNil(meta.delActionItem)) {
          if (isFunction(meta.delActionItem)) {
            actionItems.push(assign(delItem, meta.delActionItem(record)));
          } else {
            actionItems.push(assign(delItem, meta.delActionItem));
          }
        } else {
          actionItems.push(delItem);
        }

        return actionItems;
      },
    };
    return {
      registerTable,
      registerLayer,
      tableMethods,
      userInnerMethod,
      methods,
      showFooter,
      selectMethods,
      excelMethods,
    };
  }

  useHandle(emit, meta: IMetaHandleData) {
    // 当前是否是更新模式
    const isUpdate = ref<boolean>(false);

    const title = computed(() => (isNil(meta.customTitle) ? (isUpdate.value ? '编辑' : '新增') + meta.title : meta.customTitle));
    const pkidValRef = ref('');
    const pkid = meta.pkid ?? 'id';
    const { createMessage } = useMessage();
    const showFooter = ref(true);
    //注册表单
    const [registerForm, formMethods] = usePopupForm(meta.formProps);
    const callback = async (data) => {
      await formMethods.resetFields();
      if (mode == 'drawer') {
        innerMethod.setDrawerProps({ showFooter });
      }

      //初始化
      if (isFunction(meta.beforeQuery)) {
        await meta.beforeQuery();
      }
      //
      isUpdate.value = !!data?.isUpdate;

      innerMethod.changeOkLoading(false);

      if (isUpdate.value) {
        if (!isNil(meta.customDetails) && isFunction(meta.customDetails)) {
          meta.customDetails(data);
        }
        pkidValRef.value = data[pkid];
        if (!isNil(meta.details) && isFunction(meta.details)) {
          let res = await meta.details(pkidValRef.value);
          if (isFunction(meta.queryResult)) {
            res = await meta.queryResult(res);
          }
          if (!isNil(meta.pkidAlias)) {
            res[meta.pkidAlias] = res[pkid];
          }
          await formMethods.setFieldsValue(res);
          //查询结果后
          if (isFunction(meta.afterQuery)) {
            await meta.afterQuery(res);
          }
        }
      }
    };
    const mode = meta.mode ?? 'model';
    let innerObj: any = [];
    if (mode == 'model') {
      innerObj = useModalInner(callback);
    } else if (mode == 'drawer') {
      innerObj = useDrawerInner(callback);
    }
    const [registerModel, innerMethod] = innerObj;
    const methods = {
      /**
       * 提交
       */
      handleSubmit: async () => {
        try {
          await formMethods.validate();
          let values = formMethods.getFieldsValue();

          if (isFunction(meta.beforeSubmit)) {
            values = await meta.beforeSubmit(values);
          }
          innerMethod.changeOkLoading(true);
          //提交表单
          if (isFunction(meta.saveOrUpdate)) {
            await meta.saveOrUpdate(values, isUpdate.value);
          }
          if (isUpdate.value) {
            if (isFunction(meta.updateFn)) {
              const mathes = /\((.*?)\)/gm.exec(Function.prototype.toString.call(meta.updateFn));
              if (mathes?.[1]) {
                const args = mathes[1].split(',');
                if (args.length > 1) {
                  await meta.updateFn(pkidValRef.value, values);
                }
              } else {
                await meta.updateFn(values);
              }
            }
          } else {
            if (isFunction(meta.saveFn)) {
              await meta.saveFn(values);
            }
          }

          if (mode == 'model') {
            innerMethod.closeModal();
          } else {
            innerMethod.closeDrawer();
          }
          emit('success', values);
        } catch (e) {
          if (Reflect.has(e as Object, 'type')) {
            createMessage.error(Reflect.get(e as Object, 'msg'));
          }
        } finally {
          innerMethod.changeOkLoading(false);
        }
      },
    };

    return { registerForm, registerModel, methods, formMethods, title };
  }
}

export default new ApiV1();
